#include "dev.h"

#include "gtc_client_pal.h"
#include "data.h"
#include "mod_led.h"
#include "mod_rfcard.h"
#include "mod_port.h"
#include "mod_emeter.h"
#include "mod_can.h"
#include "mod_gun.h"
#include "alarm.h"
#include "log.h"
#include "utility.h"
#include "guictrl.h"
#include "errcode.h"
#include "record.h"
#include "platform.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct dc_gun_info{
    int32_t init_state;
    uint32_t poll_cnt;
    int32_t gun_link_state;
    struct CanPgn8192 pgn8192;
};

extern struct ClientUserGunInfo gun_status[];

static struct dc_gun_info gun_info[DEV_CHARGE_GUN_CNT] = {0};
static struct ClientUserBmsInfo bms_status[DEV_CHARGE_GUN_CNT]={0};

void client_sync_can512_set(struct CanChargeStartAck *data){

}

//遥测帧
void client_sync_can8192_set(struct CanPgn8192 *data){
    int index = data->gunnum - 1;
    gun_status[index].soc_percent = data->soc;
    gun_status[index].dc_charge_voltage = data->opvol*10;
    gun_status[index].dc_charge_current = (4000 - data->opcurr)*10;
    gun_status[index].ac_a_vol = 0; //3800;
    gun_status[index].ac_b_vol = 0; //3800;
    gun_status[index].ac_c_vol = 0; //3800;
    gun_status[index].ac_a_cur = 0;
    gun_status[index].ac_b_cur = 0;
    gun_status[index].ac_c_cur = 0;
    //gun_status[index].meter_kwh_num = info->meter_kwh_num;
    gun_status[index].charge_power_kw = (gun_status[index].dc_charge_voltage * gun_status[index].dc_charge_current/100)/1000;  //单位kw*100
    gun_status[index].bms_need_voltage = data->bmsneedvol*10;
    if(data->bmsneedcurr == 0){
        gun_status[index].bms_need_current = 0;
    }else{
        gun_status[index].bms_need_current = (4000 - data->bmsneedcurr)*10;
    }

    gun_status[index].bms_charge_mode = (data->chamode == 1)?2:1;
    gun_status[index].left_time = data->leftchatime;

    bms_status[index].bcl_voltage_need = data->bmsneedvol;
    bms_status[index].bcl_current_need = (4000 - data->bmsneedcurr)*10;
    bms_status[index].bcl_charge_mode = data->chamode;
    bms_status[index].bcs_test_voltage = data->bmschavolcal;
    bms_status[index].bcs_test_current = data->bmschacurrcal;
    bms_status[index].bcs_max_single_voltage = data->singlebattmaxvol;
    bms_status[index].bcs_max_single_no = 0;
    bms_status[index].bcs_current_soc = data->soc;
    bms_status[index].charge_time_left = data->leftchatime;
    bms_status[index].bsm_single_no = 0;
    bms_status[index].bsm_max_temperature = data->battmaxtemp-50;
    bms_status[index].bsm_max_temperature_check_no = 0;
    bms_status[index].bsm_min_temperature = data->battmintemp-50;
    bms_status[index].bsm_min_temperature_check_no = 0;
	bms_status[index].bsm_allow_charge = 0x01;
	
}

//充电停止完成帧
void client_sync_can4864_set(struct CanStopChargeFinish *data){
    int index = data->gunnum - 1;

    if (data->stopreason == 0x22){
        bms_status[index].bsm_voltage_too_high_or_too_low = 0x01;
    }else if (data->stopreason == 0x23){
        bms_status[index].bsm_voltage_too_high_or_too_low = 0x10;
    }
    
    if (data->stopreason == 0x24){
        bms_status[index].bsm_car_battery_soc_too_high_or_too_low = 0x01;
    }else if (data->stopreason == 0x25){
        bms_status[index].bsm_car_battery_soc_too_high_or_too_low = 0x10;
    }else {
        bms_status[index].bsm_car_battery_soc_too_high_or_too_low = 0x0;
    }

    bms_status[index].bsm_car_battery_charge_over_current = (data->stopreason == 0x26)?0x01:0x0;
    bms_status[index].bsm_battery_temperature_too_high = (data->stopreason == 0x27)?0x01:0x0;
    bms_status[index].bsm_battery_insulation_state = (data->stopreason == 0x28)?0x01:0x0;
    bms_status[index].bsm_battery_connect_state = (data->stopreason == 0x29)?0x01:0x0;

    bms_status[index].bst_bms_soc_target = data->bmsstop_soc; 
    bms_status[index].bst_bms_voltage_target = data->bmsstop_total_vol;
    bms_status[index].bst_single_voltage_target = data->bmsstop_single_vol;
    bms_status[index].bst_finish = data->bmsstop_bms_stop;
    
    bms_status[index].bst_isolation_error = data->bmsfail_isolate;
    bms_status[index].bst_connect_over_temperature = data->bmsfail_linker_over_temp;
    bms_status[index].bst_over_temperature = data->bmsfail_bms_over_temp;
    bms_status[index].bst_connect_error = data->bmsfail_linker_fail;
    bms_status[index].bst_battery_over_temperature = data->bmsfail_battery_over_temp;
    bms_status[index].bst_high_voltage_relay_error =  data->bmsfail_relay_fail;
    bms_status[index].bst_point2_test_error = data->bmsfail_check_point;
    bms_status[index].bst_other_error = data->bmsfail_other;

    bms_status[index].bst_current_too_high = data->bmserr_over_currt;
    bms_status[index].bst_voltage_too_high = data->bmserr_vol_err;
    
    bms_status[index].bst_stop_soc = data->stopsocstate;
    bms_status[index].bsd_battery_low_voltage = data->battsingleminvol;
    bms_status[index].bsd_battery_high_voltage = data->battsinglemaxvol;
    bms_status[index].bsd_battery_low_temperature = data->battmintemp-50;
    bms_status[index].bsd_battery_high_temperature = data->battmaxtemp-50;
    bms_status[index].bem_error_spn2560_00 = data->recvspn25600x00over; 
	bms_status[index].bem_error_spn2560_aa = data->recvspn25600xaaover;
	bms_status[index].bem_error_time_sync = data->recvtimesyncover;
	bms_status[index].bem_error_ready_to_charge = data->recvdevparpreover;
	bms_status[index].bem_error_receive_status = data->recvdevchastateover;
	bms_status[index].bem_error_receive_stop_charge = data->recvdevstopchaover;
	bms_status[index].bem_error_receive_report = data->recvdevcalover;
	bms_status[index].bem_error_other = data->bmsothererror;    
}

void client_sync_can8704_set(struct CanPgn8704 *data){
    gun_status[data->gunnum-1].car_connection_stat = data->car_gun_link_state; 
}

//充电启动完成帧
void client_sync_can4352_set(struct CanStartChargeFinish *data){
    int index = data->gunnum -1;
	memcpy(bms_status[index].brm_bms_connect_version, data->devbmsconnprover, sizeof(data->devbmsconnprover)); 
	bms_status[index].brm_battery_type = data->batttype;
	bms_status[index].brm_battery_power = data->batttotalah;
	bms_status[index].brm_battery_volt = data->battvolnow;

    //以下这几个暂时未取到数据
	bms_status[index].brm_battery_supplier = 0;
	bms_status[index].brm_battery_seq = 0;
	bms_status[index].brm_battery_produce_year = 2015;
	bms_status[index].brm_battery_produce_month = 1;
	bms_status[index].brm_battery_produce_day = 1;
	bms_status[index].brm_battery_charge_count = 1;
	bms_status[index].brm_battery_property_identification = 2;
    
	memcpy(bms_status[index].brm_vin,data->vin,sizeof(data->vin));
    memset(bms_status[index].brm_bms_software_version, 0xff, DEV_MAX_BRM_BMS_SOFTWARE_VERSION_LEN);
	bms_status[index].bcp_max_voltage = data->singlemaxvol/10;
	bms_status[index].bcp_max_current = data->maxcurr;
	bms_status[index].bcp_max_power = data->batttotalkwh;
	bms_status[index].bcp_total_voltage = data->bmsmaxvol;
	bms_status[index].bcp_max_temperature = data->allowmaxtemp;
	bms_status[index].bcp_battery_soc = data->totalsocstate;
	bms_status[index].bcp_battery_soc_current_voltage = data->battvolnow;
	bms_status[index].bro_bms_is_ready = 0xff;

}

struct  ClientUserBmsInfo *dev_get_user_client_bms_data(void){
    return &bms_status[0];
}

int32_t dev_init_init(uint8_t gun_id){
    can_module_clear_ack(gun_id, YC_DC_8192); //清心跳应答帧
    can_send_keeplive(gun_id,E_KEEPLIVE_NORMAL); //心跳帧
    printf("send keeplive id:%d\r\n", gun_id);
    return 0;
}

static void send_chargepara(uint8_t gun_id){
    uint8_t devid[17]={0};
    data_getstr("devid", (char_t *)devid, sizeof(devid));
    uint8_t devidbcd[8]={0};
    ASC_to_BCD(devidbcd, devid, 16);
    uint8_t sendbuf[8]={0};
    int32_t pos = 0;
    pos = ut_setnbyte(sendbuf, pos, devidbcd, 3);
    pos = ut_setnbyte(sendbuf, pos, &devidbcd[4],4);
    can_set_charging_para(gun_id, sendbuf, pos);
}

int32_t dev_is_init_succ(uint8_t gun_id){
    struct dc_gun_info *m = &gun_info[gun_id-1];
    uint8_t recv_buf[256]={0};
    int32_t ret = RET_FALSE;
    switch(m->init_state){
    case 0: //检测充电控制器心跳帧
        if (can_module_recv(gun_id, YC_DC_8192, recv_buf) > 0){
            //log(LOG_INFO, "can init 1: gun[%d] recv keeplive ack\r\n", gun_id);
            can_module_clear_ack(gun_id, CMD_VER_CHECK_ACK); //清版本校验帧应答
            can_ver_check(gun_id, 0x0110); //代表版本号为v1.10;
            m->init_state++;
            m->poll_cnt = 0;
        }else{
            m->poll_cnt++;
        }
    break;

    case 1: //检测版本校验帧应答
        if (can_module_recv(gun_id, CMD_VER_CHECK_ACK, recv_buf) > 0){
            if (recv_buf[1]==0x10 && recv_buf[2]==0x01){
                //log(LOG_INFO, "can init 2: gun[%d] recv version ack\r\n", gun_id);
                can_module_clear_ack(gun_id, CMD_CHARGE_PARA_ACK);
                send_chargepara(gun_id);
                m->poll_cnt = 0;
                m->init_state++;
            }else{
                m->init_state = 0;
                m->poll_cnt = 0;
            }
        }else{
            m->poll_cnt++;
            if (m->poll_cnt >= 3){
                m->init_state = 0;
                m->poll_cnt = 0;
            }
        }

    break;

    case 2: //检测充电参数帧应答
        if (can_module_recv(gun_id, CMD_CHARGE_PARA_ACK, recv_buf) > 0){
            if (recv_buf[1] == 0x0){
                log(LOG_INFO, "can init: gun[%d] link control board success\r\n", gun_id);
                ret = RET_TRUE;
            }else{
                m->init_state = 0;
                m->poll_cnt = 0;
            }
        }else{
            m->poll_cnt++;
            if (m->poll_cnt >= 5){
                can_send_error(gun_id, CAN_ERR_CHARGE_PARA_ACK_OVER);
                m->init_state++;
                m->poll_cnt = 0;
            }            
        }
    break;

    case 3: //检测错误帧发送
        m->poll_cnt++;
        if (m->poll_cnt >= 5){
            m->init_state = 0;
            m->poll_cnt = 0;
        }        
    break;

    default:

    break;
    }

    return ret;
}

#if 0
static int32_t state_init_pgn_ack(struct dc_gun_info *m, const void *value){
    return 0;
}
#endif
int32_t dev_idle_start(uint8_t gun_id){

    printf("state_idle_start m->id = %d\r\n",gun_id);
    can_module_clear_ack(gun_id, CMD_CHARGE_START_ACK);  //充电启动应答帧
    can_module_clear_ack(gun_id, CHARGE_START_FINSH); //充电启动完成应答帧
	can_start_charging(gun_id, 1);
    
    return 0;
}

int32_t dev_is_start_charging_finish(uint8_t gun_id, char_t *reasion){

    uint8_t recv_buf[256]={0};

    if (can_module_recv(gun_id, CMD_CHARGE_START_ACK, recv_buf) > 0){
        struct CanChargeStartAck *ack = (struct CanChargeStartAck *)recv_buf;
        if (ack->flag != 0){
            log(LOG_WARNING, "gun:%d start fail code:%d\r\n", gun_id, ack->failreason);
            memcpy(reasion, errcode_get_start_ack_fail_code(ack->failreason),4);
            return -1;
        }
    }

    if (can_module_recv(gun_id, CHARGE_START_FINSH, recv_buf) > 0){
        struct CanStartChargeFinish *startfinish = (struct CanStartChargeFinish *)recv_buf;
        if (startfinish->flag != 0){
            log(LOG_WARNING, "gun:%d start finish fail code:%d\r\n", gun_id, startfinish->failreason);
            memcpy(reasion, errcode_get_start_finish_fail_code(startfinish->failreason), 4);
            can_start_charging_finish_ack(gun_id, 0, 0x01);
            return -1;

        }else{
            can_start_charging_finish_ack(gun_id, 0, 0);
            can_module_clear_ack(gun_id, CHARGE_STOP_FINSH);  //清充电停止完成帧
            return RET_TRUE;
        }
    }
    
	return RET_FALSE;
}

int32_t dev_start_charge_fail(uint8_t gun_id, char_t *reasion){
    can_send_error(gun_id, CAN_ERR_WAIT_START_ACK_OVER);
    return 0;
}
#if 0
static void module_get_charge_time_str(uint32_t sec, char_t *str){
    if (sec < 3600){
        sprintf(str, "%d 分钟", sec/60);
    }else{
        sprintf(str, "%d 时%d 分", sec/3600,(sec%3600)/60);
    }
}
#endif
static void covert_stopreason(struct CanStopChargeFinish *stopfinish){
    if (stopfinish->recvspn25600x00over == 1){
        stopfinish->stopreason = 0x2e;
    }else if(stopfinish->recvspn25600xaaover == 1){
        stopfinish->stopreason = 0x2f;
    }else if(stopfinish->recvtimesyncover == 1){
        stopfinish->stopreason = 0x30;
    }else if(stopfinish->recvdevparpreover == 1){
        stopfinish->stopreason = 0x31;
    }else if(stopfinish->recvdevchastateover == 1){
        stopfinish->stopreason = 0x32;
    }else if(stopfinish->recvdevstopchaover == 1){
        stopfinish->stopreason = 0x33;
    }else if(stopfinish->recvdevcalover == 1){
        stopfinish->stopreason = 0x34;
    }else if(stopfinish->bmsothererror == 1){
        stopfinish->stopreason = 0x35;
    }else if(stopfinish->recvbmsover == 1){
        stopfinish->stopreason = 0x36;
    }else if(stopfinish->recvbattchaparaover == 1){
        stopfinish->stopreason = 0x37;
    }else if(stopfinish->recvbmsfinishchaparpreover == 1){
        stopfinish->stopreason = 0x38;
    }else if(stopfinish->recvbattchastateover == 1){
        stopfinish->stopreason = 0x39;
    }else if(stopfinish->recvbattchareqover == 1){
        stopfinish->stopreason = 0x3a;
    }else if(stopfinish->recvbmsstopchaover == 1){
        stopfinish->stopreason = 0x3b;
    }else if(stopfinish->recvbmschacalover == 1){
        stopfinish->stopreason = 0x3c;
    }else if(stopfinish->devothererror == 1){
        stopfinish->stopreason = 0x3d;
    }
}

int32_t dev_is_stop_charge(uint8_t gun_id, char_t *reasion){
    uint8_t recv_buf[256]={0};
    if (can_module_recv(gun_id, CHARGE_STOP_FINSH, recv_buf) > 0){
        struct CanStopChargeFinish *stopfinish = (struct CanStopChargeFinish *)recv_buf;
        log(LOG_INFO, "gun:%d stop reasion:%x\r\n", gun_id, stopfinish->stopreason);

        can_stop_charging_finish_ack(gun_id, stopfinish->stopreason);
        log(LOG_WARNING, "***begin state_charge_poll stop_reason:%x\r\n", stopfinish->stopreason);
        
        covert_stopreason(stopfinish);

        log(LOG_WARNING, "***end state_charge_poll stop_reason:%x %s\r\n", stopfinish->stopreason, errcode_get_stop_resion_code(stopfinish->stopreason));
        memcpy(reasion, errcode_get_stop_resion_code(stopfinish->stopreason), 4);

        return RET_TRUE;
    }
	return RET_FALSE;
}

int32_t dev_is_low_current(uint8_t gun_id){
    struct dc_gun_info *m = &gun_info[gun_id-1];
    if (m->pgn8192.opcurr >= 3980){ //-4000偏移量
        return RET_TRUE;
    }
    return RET_FALSE;
}

int32_t dev_stop_charge(uint8_t gun_id, char_t *reasion){
    can_module_clear_ack(gun_id, CMD_CHARGE_STOP_ACK); 
    can_module_clear_ack(gun_id, CHARGE_STOP_FINSH);
    can_stop_charging(gun_id, 0x01);
    return 0;
}

int32_t dev_is_stop_charge_finish(uint8_t gun_id){
    struct dc_gun_info *m = &gun_info[gun_id-1];
    uint8_t recv_buf[256]={0};
    if (can_module_recv(gun_id, CMD_CHARGE_STOP_ACK, recv_buf) > 0){

    }

    if (can_module_recv(gun_id, CHARGE_STOP_FINSH, recv_buf) > 0){
        struct CanStopChargeFinish *stopfinish = (struct CanStopChargeFinish *)recv_buf;
        log(LOG_INFO, "gun:%d stop reasion:%d\r\n", gun_id, stopfinish->stopreason);
    
        can_stop_charging_finish_ack(gun_id, stopfinish->stopreason);
        m->poll_cnt = 6;

        return RET_TRUE;
    }
    
    return RET_FALSE;
}

void module_update_pgn8192(int32_t gunid, struct CanPgn8192 *data){
    struct CanPgn8192 *pgn8192 = &gun_info[data->gunnum-1].pgn8192;
    pgn8192->gunnum = data->gunnum;
	pgn8192->opvol = data->opvol;
	pgn8192->opcurr = data->opcurr;
	pgn8192->soc = data->soc;
	pgn8192->battmintemp = data->battmintemp;
	pgn8192->battmaxtemp = data->battmaxtemp;
	pgn8192->singlebattmaxvol = data->singlebattmaxvol;
	pgn8192->singlebattminvol = data->singlebattminvol;
	pgn8192->devenvtemp = data->devenvtemp; 
	pgn8192->chaguidevol = data->chaguidevol;
	pgn8192->bmsneedvol = data->bmsneedvol;
	pgn8192->bmsneedcurr = data->bmsneedcurr;
	pgn8192->chamode = data->chamode;
	pgn8192->bmschavolcal = data->bmschavolcal;
	pgn8192->bmschacurrcal = data->bmschacurrcal;
	pgn8192->leftchatime = data->leftchatime;
	pgn8192->chaitftemp1 = data->chaitftemp1;
	pgn8192->chaitftemp2 = data->chaitftemp2;
	pgn8192->chaitftemp3 = data->chaitftemp3;
	pgn8192->chaitftemp4 = data->chaitftemp4;    
}

//模块
void deal_can_cmd_512(uint8_t *msg, int32_t len){
    struct CanChargeStartAck *data = (struct CanChargeStartAck *)msg;
    client_sync_can512_set(data);
    
}

void deal_can_cmd_8192(uint8_t *msg, int32_t len){
	struct CanPgn8192 *data = (struct CanPgn8192 *)msg;
    
    client_sync_can8192_set(data);
    
    module_update_pgn8192(data->gunnum, data);
}

void deal_can_cmd_8704(uint8_t *msg, int32_t len){
    struct CanPgn8704 *data = (struct CanPgn8704 *)msg;    
    //client_sync_can8704_set(data);
    
    alarm_update_total_fault(data->gunnum, data->allfail);
    alarm_update_total_alarm(data->gunnum, data->allalarm);
        
    alarm_deal(data->gunnum, DC_ALARM_BUTTON, data->e_stop_button);
    alarm_deal(data->gunnum, DC_ALARM_SMOKE, data->smoke_fail); 
    alarm_deal(data->gunnum, DC_ALARM_AC_CIRCUIT_BREAKER, data->ac_circuit_breaker);
    alarm_deal(data->gunnum, DC_ALARM_DC_BUS_CONTACT, data->dc_bus_contact); 
    alarm_deal(data->gunnum, DC_ALARM_DC_BUS_FUSE, data->dc_bus_fuse); 
    alarm_deal(data->gunnum, DC_ALARM_GUN_ELEC_LOCK, data->gun_elec_lock); 
    alarm_deal(data->gunnum, DC_ALARM_DEV_FAN, data->dev_fan); 
    alarm_deal(data->gunnum, DC_ALARM_ARRESTER, data->arrester); 
    alarm_deal(data->gunnum, DC_ALAEM_ISOLATION_CHECK, data->insulate_check); 
    alarm_deal(data->gunnum, DC_ALARM_BATTERY_REVERSE, data->battery_reverse); 
    alarm_deal(data->gunnum, DC_ALARM_CHARGING_VCG, data->charging_vcg);
    alarm_deal(data->gunnum, DC_ALARM_DEV_OVER_TEMP, data->dev_over_temp);
    alarm_deal(data->gunnum, DC_ALARM_GUN_OVER_TEMP, data->gun_over_temp);
    alarm_deal(data->gunnum, DC_ALARM_GUN_NOT_HOMING, data->gun_not_homing);
    alarm_deal(data->gunnum, DC_ALARM_BMS_COMMUNICATE, data->bms_comm_fail);
    alarm_deal(data->gunnum, DC_ALARM_VOL_IN_OVER, data->vol_in_over);
    alarm_deal(data->gunnum, DC_ALARM_VOL_IN_LOW, data->vol_in_low);
    alarm_deal(data->gunnum, DC_ALARM_DC_BUS_VOL_OVER, data->dc_bus_vol_over);
    alarm_deal(data->gunnum, DC_ALARM_DC_BUS_VOL_LOW, data->dc_bus_vol_low);
    alarm_deal(data->gunnum, DC_ALARM_DC_BUS_CURRT_OVER, data->dc_bus_curr_over);
    alarm_deal(data->gunnum, DC_ALARM_MOD_FAIL, data->mod_fail);
    alarm_deal(data->gunnum, DC_ALARM_MOD_AC_FAIL, data->mod_ac_fail);
    alarm_deal(data->gunnum, DC_ALARM_MOD_AC_VOL_OVER, data->mod_ac_vol_over);
    alarm_deal(data->gunnum, DC_ALARM_MOD_AC_VOL_LOW, data->mod_ac_vol_low);
    alarm_deal(data->gunnum, DC_ALARM_MOD_AC_LOST_PHASE, data->mod_ac_lost_phase);
    alarm_deal(data->gunnum, DC_ALARM_MOD_DC_SHORT, data->mod_dc_short);
    alarm_deal(data->gunnum, DC_ALARM_MOD_DC_CURRT_OVER, data->mod_dc_currt_over);
    alarm_deal(data->gunnum, DC_ALARM_MOD_DC_VOL_OVER, data->mod_dc_vol_over);
    alarm_deal(data->gunnum, DC_ALARM_MOD_DC_VOL_LOW, data->mod_dc_vol_low);
    alarm_deal(data->gunnum, DC_ALARM_MOD_TEMP_OVER, data->mod_temp_over);
    alarm_deal(data->gunnum, DC_ALARM_MOD_COMM_FAIL, data->mod_comm_fail);
    alarm_deal(data->gunnum, DC_ALARM_MOD_FAN_FAIL, data->mod_fan_fail);

    if(data->otherfail != 0){
        log(LOG_WARNING, "dev gun:%d other alarm code:%x\r\n", data->gunnum, data->otherfail);
        alarm_set_other_alarm_code(data->gunnum, data->otherfail);
        alarm_deal(data->gunnum, DC_ALARM_OTHER, 1);
    }else{
        alarm_deal(data->gunnum, DC_ALARM_OTHER, 0);
    }

    if (data->car_gun_link_state == 1){
        gun_info[data->gunnum-1].gun_link_state = 0;
    }else{
        gun_info[data->gunnum-1].gun_link_state = 1;
    }
}

void deal_can_cmd_4352(uint8_t *msg, int32_t len){
    struct CanStartChargeFinish *data = (struct CanStartChargeFinish *)msg;
    printf("******************************************deal_can_cmd_4352\r\n");
    client_sync_can4352_set(data);
    can_start_charging_finish_ack(data->gunnum, 1, data->flag);
}

void deal_can_cmd_4864(uint8_t *msg, int32_t len){
    struct CanStopChargeFinish *data = (struct CanStopChargeFinish *)msg;
    client_sync_can4864_set(data);
    can_stop_charging_finish_ack(data->gunnum, data->flag);
}

void deal_can_cmd_8960(uint8_t *msg, int32_t len){
    struct CanPgn8960 *data = (struct CanPgn8960 *)msg;
    alarm_deal(data->gunnum, DC_ALARM_DEV_DOOR_FAIL, data->dev_door_fail);
    alarm_deal(data->gunnum, DC_ALARM_DC_CONTACT_ADHESION, data->dc_contact_adhesion);
    alarm_deal(data->gunnum, DC_ALAEM_ISOLATION_CHECK0X23, data->insulate_check_fail);
    alarm_deal(data->gunnum, DC_ALARM_RELEASE, data->release_fail);
    alarm_deal(data->gunnum, DC_ALARM_OVER_TEMP0X23, data->dev_temp_over);
    alarm_deal(data->gunnum, DC_ALARM_GUN_OVER_TEMP0X23, data->gun_temp_over);
    alarm_deal(data->gunnum, DC_ALARM_AC_CONTACOR0X23, data->ac_contact_fail);
    alarm_deal(data->gunnum, DC_ALARM_AC_CONTACT_ADHESION0X23, data->ac_contact_adhesion);
    alarm_deal(data->gunnum, DC_ALARM_AUX_POWER0X23, data->aux_power_fail);
    alarm_deal(data->gunnum, DC_ALARM_SHUNT_CONTACT0X23, data->shunt_contact_fail);
    alarm_deal(data->gunnum, DC_ALARM_SHUNT_CONTACT_ADHESION0X23, data->shunt_contact_adhesion);
}

void can_msgdeal(uint32_t pgn, uint8_t *msg, int32_t len){
    //printf("can_recvdeal pgn:%d\r\n", pgn);
    switch(pgn){
    case CMD_CHARGE_START_ACK:
        deal_can_cmd_512(msg, len);
    break;
    case YC_DC_8192:
        deal_can_cmd_8192(msg, len);
    break;
    case YX_DC_8704:
        deal_can_cmd_8704(msg, len);
    break;
    case CHARGE_START_FINSH:
        deal_can_cmd_4352(msg, len);
    break;
    case CHARGE_STOP_FINSH:
        deal_can_cmd_4864(msg, len);
    break;
    case YX_DC_8960:
        deal_can_cmd_8960(msg, len);
    break;
    default:
    
    break;
    }
}

void controler_keeplive(uint8_t gun_id){
    can_send_8448(gun_id, 0, 0);  //can_send_8448(gun_id, m->tkwh, m->ttime); 
}

void controler_set_time(void){
    T_TimeFmt t;
    rtc_get_current_time(&t);
    rtc_set_time(t.year, t.month, t.date, t.hour, t.min, t.sec,1);
    can_time_sync(1, t.year, t.month, t.date, t.hour, t.min, t.sec);
    can_time_sync(2, t.year, t.month, t.date, t.hour, t.min, t.sec);
}

int dev_get_dev_mode(void){
    return DEV_CHARGE_MODE_DC;
}
uint8_t dev_get_relay_state(uint8_t gun_id)
{
	 return 0;
}
int32_t controler_init(void){
	if (can_module_init((can_callback)can_msgdeal) != 0){
        return -1;
    }
	return 0;
}

uint8_t dev_get_gun_link(uint8_t gun_id){
    return gun_info[gun_id-1].gun_link_state;
}

uint32_t controler_get_vol(uint8_t gun_id){
    return  gun_status[gun_id-1].dc_charge_voltage;
}

uint32_t controler_get_current(uint8_t gun_id){
    return gun_status[gun_id-1].dc_charge_current;
}

uint32_t controler_get_need_vol(uint8_t gun_id) {
    return gun_status[gun_id-1].bms_need_voltage;
}

uint32_t controler_get_need_currt(uint8_t gun_id) {
    return gun_status[gun_id-1].bms_need_current;
}

uint32_t controler_get_left_time(uint8_t gun_id) {
    return gun_status[gun_id-1].left_time;
}

uint32_t controler_get_soc(uint8_t gun_id) {
    return gun_status[gun_id-1].soc_percent;
}
